package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.TsCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.search.AttributeValueIndex;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencentcloudapi.ame.v20190916.models.Album;
import kotlin.jvm.internal.Lambda;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.language.bm.Lang;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.reactive.TransactionalOperator;
import org.springframework.util.CollectionUtils;

import javax.annotation.Nullable;
import java.util.List;
import java.util.Random;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private AlbumAttributeValueMapper albumAttributeValueMapper;

	@Autowired
	private AlbumStatMapper albumStatMapper;

	@Autowired
	private RedissonClient redissonClient;

	@Autowired
	private RabbitService rabbitService;

	/**
	 * 保存专辑
	 * @param albumInfoVo
	 * @param userId
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveAlbumInfo(AlbumInfoVo albumInfoVo, Long userId) {
		//先保存专辑信息表
		try {
			AlbumInfo albumInfo = new AlbumInfo();
			//属性赋值：前提条件是属性名必须一致
			BeanUtils.copyProperties(albumInfoVo,albumInfo);
			//前端传递的数据是否都要保存到数据表中或者保存数据表中的数据，前端都传递了嘛 校验
			//是谁创建的专辑，userId tracks_for_free(付费专辑的时候，要让他们先提前试听) status
			albumInfo.setUserId(userId);
			//设置试听,判断是否是免费不是免费的设置试听
			if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())){
				//设置免费听几集
				albumInfo.setTracksForFree(5);
			}
			// 设置审核状态：发送一个消息给管理员
			// 自定义审核通过
			albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
			//表示执行insert方法：
			albumInfoMapper.insert(albumInfo);
			//保存标签
			List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
			if (!CollectionUtils.isEmpty(albumAttributeValueVoList)){
				//如果为空那就不相等，遍历赋值
				for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
					//创建对象
					AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
					//赋值
					albumAttributeValue.setAlbumId(albumInfo.getUserId());
					albumAttributeValue.setAttributeId(albumAttributeValueVo.getAttributeId());
					albumAttributeValue.setValueId(albumAttributeValueVo.getValueId());

					albumAttributeValueMapper.insert(albumAttributeValue);
				}
			}
			saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_PLAY);
			saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_SUBSCRIBE);
			saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_BROWSE);
			saveAlbumStat(albumInfo.getId(),SystemConstant.ALBUM_STAT_COMMENT);

			//判断当前专辑是否公开 is_open=1
			if ("1".equals(albumInfo.getIsOpen())){
				//调用上架方法
				rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId());
				//将专辑Id添加到布隆过滤器
				RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
				bloomFilter.add(albumInfo.getId());
			}
		} catch (BeansException e) {
			log.error(e.getMessage(),e);
			throw new GuiguException(ResultCodeEnum.SERVICE_ERROR);
//			return false;
		}
		return true;
	}

	public void saveAlbumStat(Long id, String albumStatComment) {
		//创建对象
		AlbumStat albumStat = new AlbumStat();
		albumStat.setAlbumId(id);
		albumStat.setStatNum(new Random().nextInt(1000000));
		albumStat.setStatType(albumStatComment);
		albumStatMapper.insert(albumStat);
	}

	/**
	 * 分页查询列表
	 * @param page
	 * @param albumInfoQuery
	 * @return
	 */
	@Override
	public IPage<AlbumListVo> findUserAlbumPage(Page<AlbumListVo> page, AlbumInfoQuery albumInfoQuery) {
		return albumInfoMapper.selectUserAlbumPage(page,albumInfoQuery);
	}

	/**
	 * 删除专辑
	 * @param albumId
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void removeAlbumInfo(Long albumId) {
		//删除album_info
		albumInfoMapper.deleteById(albumId);
		//删除album_attribute_value
		albumAttributeValueMapper.delete(
				new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));
		//删除统计信息
		albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId,albumId));
	}

	/**
	 * 根据Id获取详情信息
	 * @param albumId
	 * @return
	 */
	@Nullable
	public AlbumInfo getAlbumInfoDB(Long albumId) {
		//先查询专辑信息表，因为是修改，所以判断是否为空
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		//判断是否为空
		if (null != albumInfo){
			//不为空查询构建的条件
			LambdaQueryWrapper<AlbumAttributeValue> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(AlbumAttributeValue::getAlbumId,albumId);
			List<AlbumAttributeValue> albumAttributeValueList = albumAttributeValueMapper.selectList(wrapper);
			albumInfo.setAlbumAttributeValueVoList(albumAttributeValueList);
		}
		//返回数据
		return albumInfo;
	}

	/**
	 * 根据专辑id更新专辑信息
	 * @param albumId
	 * @param albumInfoVo
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
		//创建对象
		AlbumInfo albumInfo = new AlbumInfo();
		//把相同的字段拷贝
		BeanUtils.copyProperties(albumInfoVo,albumInfo);
		//修改一下登录进来的id
		albumInfo.setId(albumId);
		//调用mapper修改id
		albumInfoMapper.updateById(albumInfo);
		//由于修改值的时候未触发控制器，所以要先删除后修改
		albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
				.eq(AlbumAttributeValue::getAlbumId,albumId));
		List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
		//确认是否添加成功添加成功就遍历修改
		if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
			//遍历修改数据
			for (AlbumAttributeValueVo albumAttributeValueVo : albumAttributeValueVoList) {
				//创建修改的实体对象
				AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
				//属性拷贝
				BeanUtils.copyProperties(albumAttributeValueVo,albumAttributeValue);
				albumAttributeValue.setAlbumId(albumId);
				albumAttributeValueMapper.insert(albumAttributeValue);
			}
		}
		//判断专辑是否公开 is_open = 1 ;
		if ("1".equals(albumInfo.getIsOpen())){
			//调用上架方法
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_UPPER,albumInfo.getId());
			//将专辑Id添加到布隆过滤器
			RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
			bloomFilter.add(albumInfo.getId());
		}else {
			//调用下架方法
			rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM,MqConst.ROUTING_ALBUM_LOWER,albumInfo.getId());
		}
	}

	/**
	 * 获取专辑列表
	 * @param userId
	 * @return
	 */
	@Override
	public List<AlbumInfo> findUserAllAlbumList(Long userId) {
		//构建查询条件
		LambdaQueryWrapper<AlbumInfo> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(AlbumInfo::getUserId,userId);
		//因为数据太多进行分页
		Page<AlbumInfo> albumInfoPage = new Page<>(1,100);
		Page<AlbumInfo> infoPage = albumInfoMapper.selectPage(albumInfoPage, wrapper);
		return infoPage.getRecords();
	}

	@Override
	@TsCache(keyPrefix = "statVo:")
	public AlbumStatVo getAlbumStatVo(Long albumId) {

		return albumInfoMapper.selectAlbumStatVo(albumId);
	}

	@TsCache(keyPrefix = "album:",keySuffix = ":info")
	@Override
	public AlbumInfo getAlbumInfo(Long albumId) {
		return getAlbumInfoDB(albumId);
		//  定义String 数据类型；
		//        String dataKey = RedisConstant.ALBUM_INFO_PREFIX + albumId;
		//        try {
		//            //  根据缓存的key获取数据;
		//            AlbumInfo albumInfo = (AlbumInfo) this.redisTemplate.opsForValue().get(dataKey);
		//            //  判断缓存中是否存在数据;
		//            if (null == albumInfo){
		//                System.out.println("缓存没有数据!");
		//                //  不存在; 查询数据库;
		//                //  加锁;
		//                String lockKey = RedisConstant.ALBUM_LOCK_SUFFIX + albumId;
		//                RLock lock = redissonClient.getLock(lockKey);
		//                lock.lock();
		//                try {
		//                    //  查询数据库之前，再判断一次缓存;
		//                    albumInfo = (AlbumInfo) this.redisTemplate.opsForValue().get(dataKey);
		//                    if (null != albumInfo){
		//                        return albumInfo;
		//                    }
		//                    //  业务逻辑;
		//                    albumInfo = getAlbumInfoDB(albumId);
		//                    //  判断数据是否为空：
		//                    if (null == albumInfo){
		//                        //  防止穿透; 设置一个空值;
		//                        this.redisTemplate.opsForValue().set(dataKey,new AlbumInfo(),RedisConstant.ALBUM_TEMPORARY_TIMEOUT, TimeUnit.SECONDS);
		//                        return new AlbumInfo();
		//                    }
		//                    //  数据库中有数据;
		//                    this.redisTemplate.opsForValue().set(dataKey,albumInfo,RedisConstant.ALBUM_TIMEOUT, TimeUnit.SECONDS);
		//                    //  返回数据;
		//                    return albumInfo;
		//                } catch (Exception e) {
		//                    //  异常信息;
		//                    log.error(e.getMessage(),e);
		//                } finally {
		//                    //  解锁：
		//                    lock.unlock();
		//                }
		//            } else {
		//                //  缓存有数据
		//                System.out.println("缓存有数据");
		//                return albumInfo;
		//            }
		//        } catch (Exception e) {
		//            log.error(e.getMessage(),e);
		//        }
		//        //  数据库兜底操作;
		//        return getAlbumInfoDB(albumId);
	}
}
